﻿package core.image
{
    import core.enum.*;
    import core.ui.*;
    import flash.geom.*;

    public class History extends Object
    {
        private var size:int;
        public var undo:Array;
        public var redo:Array;
        private var entry:HistoryEntry;
        public var prepare:HistoryEntry;
        var ed:Tuyitu;
        var canvas:Canvas;
        var document:Document;

        public function History(param1:Tuyitu, param2:Canvas, param3:int)
        {
            this.ed = param1;
            this.canvas = param2;
            this.document = param2.document;
            this.size = param3;
            this.undo = new Array();
            this.redo = new Array();
            return;
        }// end function

        public function Prepare(Tuyitu:Action, Tuyitu:Boolean = false) : void
        {
            this.prepare = this.GetState(Tuyitu, this.document.anr, false);
            if (Tuyitu)
            {
                this.Commit();
            }
            return;
        }// end function

        public function ChangePrepareType(Tuyitu:Action) : void
        {
            if (this.prepare != null)
            {
                this.prepare.type = Tuyitu;
            }
            return;
        }// end function

        public function Commit() : void
        {
            if (this.prepare != null)
            {
                this.undo.push(this.prepare);
                while (this.undo.length > this.size)
                {
                    
                    this.undo.shift();
                }
                while (this.redo.length > 0)
                {
                    
                    this.redo.shift();
                }
                U.Log(this.prepare.type.name);
                this.prepare = null;
                this.ed.history.Update();
            }
            return;
        }// end function

        public function Did(param1:HistoryEntry)
        {
            this.prepare = param1;
            this.Commit();
            return;
        }// end function

        public function get IsEmpty() : Boolean
        {
            return Boolean(this.undo.length == 0 || this.undo.length == 1 && ((this.undo[0] as HistoryEntry).type == Action.Open || (this.undo[0] as HistoryEntry).type == Action.New));
        }// end function

        public function Undo(Canvas:int = 1) : Boolean
        {
            var _loc_2:Boolean = false;
            var _loc_3:int = 0;
            while (_loc_3 < Canvas)
            {
                
                if (this.undo.length > 1)
                {
                    this.entry = this.undo.pop() as HistoryEntry;
                    this.redo.push(this.GetState(this.entry.type, this.entry.nr, true));
                    this.SetState();
                    _loc_2 = true;
                }
                _loc_3++;
            }
            this.ed.history.Update();
            return _loc_2;
        }// end function

        public function Redo(Canvas:int = 1) : Boolean
        {
            var _loc_2:Boolean = false;
            var _loc_3:int = 0;
            while (_loc_3 < Canvas)
            {
                
                if (this.redo.length > 0)
                {
                    this.entry = this.redo.pop() as HistoryEntry;
                    this.undo.push(this.GetState(this.entry.type, this.entry.nr, false));
                    this.SetState();
                    _loc_2 = true;
                }
                _loc_3++;
            }
            this.ed.history.Update();
            return _loc_2;
        }// end function

        public function GetState(Boolean:Action, Boolean:int, Boolean:Boolean) : HistoryEntry
        {
            switch(Boolean)
            {
                case Action.DocumentNewsize:
                case Action.DocumentResize:
                case Action.DocumentRotate:
                case Action.DocumentFlip:
                case Action.CropTool:
                case Action.LayerMerge:
                {
                    return this.GetDocumentState(Boolean);
                }
                case Action.SelectAll:
                case Action.Deselect:
                case Action.WandTool:
                case Action.FreehandLassoTool:
                case Action.PolygonLassoTool:
                case Action.EllipticalMarqueeTool:
                case Action.RectangularMarqueeTool:
                case Action.InvertSelection:
                case Action.SelectionMove:
                {
                    return this.GetSelectionState(Boolean);
                }
                case Action.LayerRemove:
                {
                    if (Boolean)
                    {
                        return this.GetTypeState(Boolean, Boolean);
                    }
                    return this.GetLayerState(Boolean, Boolean);
                }
                case Action.LayerPaste:
                case Action.LayerAddText:
                case Action.LayerAddShape:
                case Action.LayerAddBitmap:
                case Action.LayerDublicate:
                {
                    if (Boolean)
                    {
                        return this.GetLayerState(Boolean, Boolean);
                    }
                    return this.GetTypeState(Boolean, Boolean);
                }
                case Action.LayerMove:
                {
                    return this.GetLayerPositionState(Boolean, Boolean);
                }
                case Action.Cut:
                case Action.MoveCut:
                case Action.Distort:
                case Action.Transform:
                {
                    return this.GetLayerAndSelectionState(Boolean, Boolean);
                }
                case Action.LayerOrder:
                {
                    return new HistoryEntry(Boolean, this.entry.args[0], Boolean);
                }
                default:
                {
                    return this.GetLayerState(Boolean, Boolean);
                    break;
                }
            }
        }// end function

        public function GetDocumentState(Boolean:Action) : HistoryEntry
        {
            var _loc_3:int = 0;
            var _loc_2:* = new Array(this.document.numChildren);
            while (_loc_3 < _loc_2.length)
            {
                
                _loc_2[_loc_3] = (this.document.getChildAt(_loc_3) as Layer).Clone();
                _loc_3++;
            }
            return new HistoryEntry(Boolean, 0, _loc_2, this.document.dw, this.document.dh);
        }// end function

        public function GetSelectionState(Boolean:Action) : HistoryEntry
        {
            if (this.canvas.selection != null)
            {
                return new HistoryEntry(Boolean, 0, this.canvas.selection.Clone());
            }
            return new HistoryEntry(Boolean, 0);
        }// end function

        public function GetLayerAndSelectionState(Boolean:Action, Boolean:int) : HistoryEntry
        {
            var _loc_3:* = this.document.GetLayer(Boolean).Clone();
            var _loc_4:* = this.canvas.selection != null ? (this.canvas.selection.Clone()) : (null);
            return new HistoryEntry(Boolean, Boolean, _loc_3, _loc_4);
        }// end function

        public function GetLayerPositionState(Boolean:Action, Boolean:int) : HistoryEntry
        {
            var _loc_3:* = this.document.GetLayer(Boolean);
            return new HistoryEntry(Boolean, Boolean, new Point(_loc_3.x, _loc_3.y));
        }// end function

        public function GetLayerState(Boolean:Action, Boolean:int) : HistoryEntry
        {
            var _loc_3:* = this.document.GetLayer(Boolean);
            return new HistoryEntry(Boolean, Boolean, _loc_3.Clone());
        }// end function

        public function GetTypeState(Boolean, Boolean:int) : HistoryEntry
        {
            return new HistoryEntry(Boolean, Boolean);
        }// end function

        public function SetState() : void
        {
            var _loc_1:Array = null;
            var _loc_2:Layer = null;
            var _loc_3:Point = null;
            var _loc_4:Layer = null;
            var _loc_5:Layer = null;
            var _loc_6:Layer = null;
            var _loc_7:Layer = null;
            var _loc_8:int = 0;
            switch(this.entry.type)
            {
                case Action.SelectAll:
                case Action.Deselect:
                case Action.WandTool:
                case Action.FreehandLassoTool:
                case Action.PolygonLassoTool:
                case Action.EllipticalMarqueeTool:
                case Action.RectangularMarqueeTool:
                case Action.InvertSelection:
                case Action.SelectionMove:
                {
                    this.canvas.SetSelection(this.entry.args[0]);
                    break;
                }
                case Action.DocumentNewsize:
                case Action.DocumentResize:
                case Action.DocumentRotate:
                case Action.DocumentFlip:
                case Action.CropTool:
                {
                    this.document.dw = this.entry.args[1];
                    this.document.dh = this.entry.args[2];
                    this.canvas.SetImageSizeInfo(this.document.dw, this.document.dh);
                }
                case Action.LayerMerge:
                {
                    this.document.Clear();
                    _loc_1 = this.entry.args[0] as Array;
                    _loc_8 = 0;
                    while (_loc_8 < _loc_1.length)
                    {
                        
                        this.document.AddLayer((_loc_1[_loc_8] as Layer).Clone());
                        _loc_8++;
                    }
                    this.canvas.UpdateHolderSize();
                    this.canvas.UpdateAfterEdit();
                    this.ed.navigator.SetReference(this.canvas);
                    this.ed.layers.SetReference(this.canvas.document);
                    break;
                }
                case Action.LayerOrder:
                {
                    this.document.LayerOrder(this.entry.args[0], this.entry.nr);
                    this.ed.layers.Update();
                    this.ed.tool.Reset();
                    break;
                }
                case Action.LayerMove:
                {
                    _loc_2 = this.document.GetLayer(this.entry.nr);
                    _loc_3 = this.entry.args[0] as Point;
                    _loc_2.x = _loc_3.x;
                    _loc_2.y = _loc_3.y;
                    this.canvas.UpdateAfterEdit();
                    break;
                }
                case Action.LayerRasterize:
                case Action.LayerMaskApply:
                {
                    _loc_4 = this.entry.args[0] as Layer;
                    this.document.RemoveLayer(this.entry.nr);
                    this.document.AddLayer(_loc_4, this.entry.nr);
                    this.ed.layers.Update();
                    this.ed.tool.Reset();
                    break;
                }
                case Action.LayerPaste:
                case Action.LayerRemove:
                case Action.LayerAddText:
                case Action.LayerAddShape:
                case Action.LayerAddBitmap:
                case Action.LayerDublicate:
                {
                    if (this.entry.args.length == 0)
                    {
                        this.document.RemoveLayer(this.entry.nr);
                    }
                    else
                    {
                        this.document.AddLayer(this.entry.args[0] as Layer, this.entry.nr);
                    }
                    this.ed.layers.Update();
                    this.ed.tool.Reset();
                    break;
                }
                case Action.LayerMaskAdd:
                case Action.LayerMaskRemove:
                {
                    _loc_5 = this.document.GetLayer(this.entry.nr);
                    _loc_6 = this.entry.args[0] as Layer;
                    if (!_loc_6.hasMask)
                    {
                        _loc_5.RemoveMask();
                    }
                    else
                    {
                        _loc_5.AddMask(_loc_6.masking.bitmapData);
                    }
                    this.ed.layers.Update();
                    this.ed.tool.Reset();
                    break;
                }
                case Action.LayerOpacity:
                {
                    this.ed.layers.Update();
                    this.ed.tool.Reset();
                    break;
                }
                case Action.Cut:
                case Action.MoveCut:
                case Action.Distort:
                case Action.Transform:
                {
                    this.canvas.SetSelection(this.entry.args[1]);
                }
                default:
                {
                    _loc_7 = this.document.GetLayer(this.entry.nr);
                    _loc_4 = this.entry.args[0] as Layer;
                    _loc_7.x = _loc_4.x;
                    _loc_7.y = _loc_4.y;
                    if (_loc_7.type == LayerType.Bitmap)
                    {
                        if (_loc_4.bitmap != null && _loc_4.bitmap.bitmapData != null)
                        {
                            if (_loc_7.bitmap == null)
                            {
                                _loc_7.AddBitmap(_loc_4.bitmap.bitmapData);
                            }
                            else
                            {
                                _loc_7.bitmap.bitmapData = _loc_4.bitmap.bitmapData;
                            }
                        }
                        else if (_loc_7.bitmap.bitmapData != null)
                        {
                            _loc_7.bitmap.bitmapData.dispose();
                            _loc_7.bitmap.bitmapData = null;
                        }
                        if (_loc_7.hasMask)
                        {
                            if (_loc_4.masking != null && _loc_4.masking.bitmapData != null)
                            {
                                _loc_7.masking.bitmapData = _loc_4.masking.bitmapData;
                            }
                            else
                            {
                                _loc_7.masking.bitmapData.dispose();
                                _loc_7.masking.bitmapData = null;
                            }
                        }
                        this.canvas.UpdateAfterEdit(this.entry.nr);
                    }
                    break;
                }
            }
            this.entry = null;
            return;
        }// end function

    }
}
